package framework.resolver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.openems.entity.Entity;
import org.openems.entity.Key;

import framework.Accessor;
import framework.AccessorHelper;
import framework.AccessorHelperImpl;
import framework.Resolver;

public abstract class ResolverHelper implements Resolver {
	private Map<Key, List<UnitResolver>> resolvers = new HashMap<Key, List<UnitResolver>>();
	private Accessor hookAccessor;
	private Accessor accessor;
	private AccessorHelper accessorHelper;
	
	abstract protected void configure(UnitResolverRegister register);
	
	public ResolverHelper() {
		configure(new UnitResolverRegister() {
			@Override
			public void add(Key key, UnitResolver unitResolver) {
				getResolverList(key).add(unitResolver);
			}
		});
		
		accessorHelper = new AccessorHelperImpl(new Accessor() {
			@Override
			public Entity get(Key key) {
				return accessor.get(key);
			}

			@Override
			public void put(Entity newEntity) {
				Entity oldEntity = accessor.get(newEntity.getKey());
				if (!oldEntity.equals(newEntity)) {
					accessor.put(newEntity);
					doResolve(oldEntity, newEntity);
				}
			}
		});
	}
				
	@Override
	public void resolve(final Accessor accessor, Entity oldEntity, Entity newEntity) {
		this.accessor = accessor;
		doResolve(oldEntity, newEntity);
	}

	private void doResolve(Entity oldEntity, Entity newEntity) {
		List<UnitResolver> resolvers = this.resolvers.get(newEntity.getKey());
		if (resolvers != null) {
			for (UnitResolver resolver : resolvers) {
				resolver.resolve(oldEntity, newEntity, accessorHelper);
			}
		}
	}
	
	public void add(Key key, UnitResolver resovler) {
		getResolverList(key).add(resovler);
	}

	private List<UnitResolver> getResolverList(Key key) {
		if (resolvers.get(key) == null) {
			resolvers.put(key, new ArrayList<UnitResolver>());
		}
		return resolvers.get(key);
	}	
}
